<script setup>
import { ref } from 'vue'

defineProps({
  msg: String,
})


const inputText = ref('')
const cleanText = ref('')
const hexArray = ref([])
const logMessages = ref([])  // 添加日志数组
const checkSum = ref('')
const showTestNetworkButton = ref < Boolean > (false);
// 表头数据
const headers = ref(['序号', '十进制', '十六进制', '二进制'])

// 表格数据（响应式）
const tableData = ref([
])

const addLog = (message) => {
  console.log(message)  // 控制台输出
  //logMessages.value.push(message)  // 添加到日志数组
}

const addMessage = (key, value) => {
  logMessages.value.push({
    key: key,
    value: value
  })
}

const convertToHexArray = () => {
  // 清除空格和0x
  cleanText.value = inputText.value
    .replace(/\s+/g, '')  // 清除所有空格
    .replace(/0x/gi, '')  // 清除0x字符（不区分大小写）
  addLog(cleanText.value)
  addLog(cleanText.value.length)
  // 将文本转换为十六进制数组
  const result = []
  tableData.value.length = 0
  logMessages.value.length = 0
  for (let i = 0; i < cleanText.value.length; i += 2) {
    const hex = cleanText.value.slice(i, i + 2)
    if (hex.length === 2) {
      const decimalism = parseInt(hex, 16)
      const hexadecimal = decimalism.toString(16)
      const binary = decimalism.toString(2).padStart(8, '0')
      tableData.value.push({ id: i / 2, decimalism: decimalism, hexadecimal: hexadecimal, binary: binary })
      addLog(decimalism + "-" + hexadecimal + "-" + binary)
      result.push(hex)

    }
  }
  processResult(result)
  hexArray.value = result

  // 将 result 数组转换为十六进制字符串
  const hexString = result.join('');
  // 计算和校验值
  let checksum = 0;
  for (let i = 0; i < hexString.length; i += 2) {
    const hex = hexString.slice(i, i + 2);
    checksum += parseInt(hex, 16);
  }

  // 将和校验值转换为两位的十六进制字符串
  const checksumHex = '' + (checksum % 65536).toString(16).toUpperCase().padStart(4, '0');
  checkSum.value = checksumHex
  // 将和校验值推入 tableData
  // tableData.value.push({ id: tableData.value.length, decimalism: checksum % 256, hexadecimal: checksumHex, binary: (checksum % 256).toString(2).padStart(8, '0') });


  // 添加日志
  addLog('十六进制数组: ' + JSON.stringify(hexArray.value))

  // 将十六进制字符串转换为数字后再比较
  const a = parseInt(hexArray.value[0], 16)
  addLog('转换后的数值a: ' + a)


  // 按位运算
  const bitAnd1 = a & 1;        // 与运算
  const bitAnd2 = a & 1 << 1;     // 与运算
  const bitAnd3 = a & 1 << 2;     // 与运算
  const bitAnd4 = a & 1 << 3;     // 与运算
  const bitAnd5 = a & 1 << 4;     // 与运算
  const bitAnd6 = a & 1 << 5;     // 与运算
  const bitAnd7 = a & 1 << 6;     // 与运算
  const bitAnd8 = a & 1 << 7;     // 与运算
  const bitOr = a | 1;         // 或运算
  const bitXor = a ^ 1;        // 异或运算
  const bitNot = ~a;           // 非运算
  const bitLeft = a << 1;      // 左移
  const bitRight = a >> 1;     // 右移
  const bitRightZero = a >>> 1;// 无符号右移

  // 创建数据对象
  const data = {
    originalValue: a,
    binary: a.toString(2).padStart(8, '0'),
    bitOperations: {
      and: {
        bit0: bitAnd1,
        bit1: bitAnd2,
        bit2: bitAnd3,
        bit3: bitAnd4,
        bit4: bitAnd5,
        bit5: bitAnd6,
        bit6: bitAnd7,
        bit7: bitAnd8
      },
      or: bitOr,
      xor: bitXor,
      not: bitNot,
      shift: {
        left: bitLeft,
        right: bitRight,
        rightZero: bitRightZero
      }
    }
  }



  // 转换为JSON并打印
  const jsonString = JSON.stringify(data, null, 2)
  addLog('JSON数据：\n' + jsonString)

  // 打印所有按位运算结果
  // addLog('按位与(&)运算: ' + a + ' & 1 = ' + bitAnd1)
  // addLog('按位与(&)运算: ' + a + ' & 1<<1 = ' + bitAnd2)
  // addLog('按位与(&)运算: ' + a + ' & 1<<2 = ' + bitAnd3)
  // addLog('按位与(&)运算: ' + a + ' & 1<<3 = ' + bitAnd4)
  // addLog('按位与(&)运算: ' + a + ' & 1<<4 = ' + bitAnd5)
  // addLog('按位与(&)运算: ' + a + ' & 1<<5 = ' + bitAnd6)
  // addLog('按位与(&)运算: ' + a + ' & 1<<6 = ' + bitAnd7)
  // addLog('按位与(&)运算: ' + a + ' & 1<<7 = ' + bitAnd8)
  // addLog('按位或(|)运算: ' + a + ' | 1 = ' + bitOr)
  // addLog('按位异或(^)运算: ' + a + ' ^ 1 = ' + bitXor)
  // addLog('按位非(~)运算: ~' + a + ' = ' + bitNot)
  // addLog('左移(<<)运算: ' + a + ' << 1 = ' + bitLeft)
  // addLog('右移(>>)运算: ' + a + ' >> 1 = ' + bitRight)
  // addLog('无符号右移(>>>)运算: ' + a + ' >>> 1 = ' + bitRightZero)

  // 打印二进制表示
  addLog('二进制表示: ' + a.toString(2).padStart(8, '0'))

  if (a === 18) {
    addLog('a is 18')
  } else {
    addLog('a is not 18')
  }
}

const processResult = (result) => {
  console.log(result)
  if (parseInt(result[0], 16) != 0x3A || parseInt(result[1], 16) != 0xF0) {
    addMessage("起始位不是3AF0")
    return false
  }
  if (parseInt(result[2], 16) != 0x03) {
    addMessage("功能码不是03")
    return false
  }
  if (parseInt(result[3], 16) != (result.length - 6)) {
    addMessage("长度不对，数据域长度为" + parseInt(result[3], 16) + "，数据包长度为" + (result.length - 6))
    return false
  }
  if (result[4] != 0) {
    addMessage("子功能码不是00")
    return false
  }
  //功能码
  if (parseInt(result[5], 16) == 2) {
    addMessage("微蒸烤功能码是02", "控制下行")
    processResultDown(result)
  } else if (parseInt(result[5], 16) == 3 && parseInt(result[6], 16) == 1) {
    addMessage("微蒸烤功能码是0301", "查询上行")
    processResultUp(result)
  } else if (parseInt(result[5], 16) == 4 && parseInt(result[6], 16) == 1) {
    addMessage("微蒸烤功能码是0401", "主动上报")
    processResultUp(result)
  }

}

const processResultDown = (result) => {
  if (parseInt(result[6], 16) == 1) {
    addMessage("微蒸烤子功能码是01", "烹饪模式类工作控制")
    let recipeId = parseInt(result[7], 16) * 256 * 256 + parseInt(result[8], 16) * 256 + parseInt(result[9], 16)
    addMessage("菜谱id", recipeId)
    let multiCookFlag = result[10]
    addMessage("多段烹饪标识", multiCookFlag)
    let preheatCavityFlag = result[11]
    addMessage("预热/腔体标识", preheatCavityFlag)
    let modelId = parseInt(result[12], 16) * 256 + parseInt(result[13], 16)
    addMessage("模式id", modelId)
    let setTimeHour = parseInt(result[14], 16)
    addMessage("设置时间-时", setTimeHour)
    let setTimeMinute = parseInt(result[15], 16)
    addMessage("设置时间-分", setTimeMinute)
    let setTimeSecond = parseInt(result[16], 16)
    addMessage("设置时间-秒", setTimeSecond)
    let setFirePower = parseInt(result[17], 16)
    addMessage("设置微波功率", setFirePower)
    let setUpTemp = parseInt(result[18], 16) * 256 + parseInt(result[19], 16)
    addMessage("设置上管温度", setUpTemp)
    let setDownTemp = parseInt(result[20], 16) * 256 + parseInt(result[21], 16)
    addMessage("设置下管温度", setDownTemp)
    let setProbeTemp = parseInt(result[22], 16) * 256 + parseInt(result[23], 16)
    addMessage("设置探针温度", setProbeTemp)
    let setStreamLevel = parseInt(result[24], 16)
    addMessage("设置蒸汽档位", setStreamLevel)
    let setWeight = parseInt(result[25], 16)
    addMessage("设置重量/份量", setWeight)
    let setFinishAction = parseInt(result[26], 16)
    if (setFinishAction == 0) {
      addMessage("工作结束后处理", "自动进入下一段烹饪")
    } else if (setFinishAction == 1) {
      addMessage("工作结束后处理", "等待20秒后，自动进入下一段烹饪")
    } else if (setFinishAction == 2) {
      addMessage("工作结束后处理", "需用户确认才进入下一段烹饪，等待超20分钟后，返回待机")
    } else if (setFinishAction == 0xff) {
      addMessage("工作结束后处理", "无操作 / 不设置")
    }

  } else if (parseInt(result[6], 16) == 2) {
    addMessage("微蒸烤子功能码是02", "辅件控制")
    let standyFlag = parseInt(result[7], 16)
    switch (standyFlag) {
      case 1:
        addMessage("待机标识", "01省电/关机")
        break;
        case 2:
        addMessage("待机标识", "02取消工作")
        break;
        case 3:
        addMessage("待机标识", "03继续制作/跳过")
        break;
        case 6:
        addMessage("待机标识", "06永久暂停")
        break;
    }
    let childLockFlag = parseInt(result[8], 16)
     addMessage("童锁", childLockFlag>0? "开启":"关闭")
    let lampFlag = parseInt(result[9], 16)
    addMessage("灯光", lampFlag>0? "开启":"关闭")
    let doorFlag = parseInt(result[11], 16)
     addMessage("炉门", lampFlag>0? "开启":"关闭")



  } else if (parseInt(result[6], 16) == 3) {
    addMessage("微蒸烤功能码是03", "工作中参数调整")
    let paramsControlModel =  parseInt(result[7], 16)
    if(paramsControlModel == 1) {
      addMessage("参数控制模式", "01设置量/部分参数控制")
      let controlNum = parseInt(result[8], 16)
      addMessage("控制参数数量", controlNum)
      let startIndex = 9
      for(let i=0;i<controlNum;i++){
        startIndex = processControl(result, startIndex)
      }
    } else if(paramsControlModel == 2) {
      addMessage("参数控制模式", "02增量/部分参数控制")  
    } else if(paramsControlModel == 3) {
      addMessage("参数控制模式", "03减量/部分参数控制")
    }
  }
}


const processControl = (result) => {
  if(parseInt(result[startIndex], 16)==0){
        let controlSteamLevel = parseInt(result[startIndex+1], 16)
        addMessage("控制蒸汽档位", "蒸汽档位 "+controlSteamLevel)
        startIndex += 2
      }
      if(parseInt(result[startIndex], 16)==1){
        let controlTimeHour = parseInt(result[startIndex+1], 16)
        let controlTimeMinute = parseInt(result[startIndex+2], 16)
        let controlTimeSecond = parseInt(result[startIndex+3], 16)
        addMessage("控制时间-时", controlTimeHour)
        addMessage("控制时间-分", controlTimeMinute)
        addMessage("控制时间-秒", controlTimeSecond)
        startIndex += 4
      }
      if(parseInt(result[startIndex], 16)==2){
        let controlFirePower = parseInt(result[startIndex+1], 16)
        addMessage("控制功率", controlFirePower)
        startIndex += 2
      }
      if(parseInt(result[startIndex], 16)==3){
        let controlTempUnit = parseInt(result[startIndex+1], 16)
        let controlTemp = parseInt(result[startIndex+2], 16) * 256 + parseInt(result[startIndex+3], 16)
        addMessage("控制温度", "单位"+controlTempUnit+"，温度"+controlTemp)
        startIndex += 4
      }
      if(parseInt(result[startIndex], 16)==4){
        let controlProbeTempUnit = parseInt(result[startIndex+1], 16)
        let controlProbeTemp = parseInt(result[startIndex+2], 16) * 256 + parseInt(result[startIndex+3], 16)
        addMessage("探针温度", "单位"+controlProbeTempUnit+"，温度"+controlProbeTemp)
         startIndex += 4
      }
      if(parseInt(result[startIndex], 16)==5){
        let controlZoneTempUnit = parseInt(result[startIndex+1], 16)
        let controlZoneCavity = parseInt(result[startIndex+2], 16)
        let controlZonePipe = parseInt(result[startIndex+3], 16)
        let controlZoneTemp = parseInt(result[startIndex+4], 16) * 256 + parseInt(result[startIndex+5], 16)
        addMessage("腔体上下管", "单位"+controlZoneTempUnit+"，腔体"+controlZoneCavity+"，上下管"+controlZonePipe+"，温度"+controlZoneTemp)
        startIndex += 6
      }
      return startIndex
}

const processResultUp = (result) => {

  let recipeId = parseInt(result[8], 16) * 256 * 256 + parseInt(result[9], 16) * 256 + parseInt(result[10], 16)
  addMessage("菜谱id", recipeId)
  let multiCookFlag = result[11]
  addMessage("多段烹饪标识", multiCookFlag)
  let preheatCavityFlag = result[12]
  addMessage("预热/腔体标识", preheatCavityFlag)
  let modelId = parseInt(result[13], 16) * 256 + parseInt(result[14], 16)
  addMessage("模式id", modelId)
  let setTimeHour = parseInt(result[15], 16)
  addMessage("设置时间-时", setTimeHour)
  let setTimeMinute = parseInt(result[16], 16)
  addMessage("设置时间-分", setTimeMinute)
  let setTimeSecond = parseInt(result[17], 16)
  addMessage("设置时间-秒", setTimeSecond)
  let setFirePower = parseInt(result[18], 16)
  addMessage("设置微波功率", setFirePower)
  let setUpTemp = parseInt(result[19], 16) * 256 + parseInt(result[20], 16)
  addMessage("设置上管温度", setUpTemp)
  let setDownTemp = parseInt(result[21], 16) * 256 + parseInt(result[22], 16)
  addMessage("设置下管温度", setDownTemp)
  let setProbeTemp = parseInt(result[23], 16) * 256 + parseInt(result[24], 16)
  addMessage("设置探针温度", setProbeTemp)
  let setStreamLevel = parseInt(result[25], 16)
  addMessage("设置蒸汽档位", setStreamLevel)
  let setWeight = parseInt(result[26], 16)
  addMessage("设置重量/份量", setWeight)
  let setFinishAction = parseInt(result[27], 16)
  if (setFinishAction == 0) {
    addMessage("工作结束后处理", "自动进入下一段烹饪")
  } else if (setFinishAction == 1) {
    addMessage("工作结束后处理", "等待20秒后，自动进入下一段烹饪")
  } else if (setFinishAction == 2) {
    addMessage("工作结束后处理", "需用户确认才进入下一段烹饪，等待超20分钟后，返回待机")
  } else if (setFinishAction == 0xff) {
    addMessage("工作结束后处理", "无操作 / 不设置")
  }
  let remainTimeHour = parseInt(result[28], 16)
  addMessage("剩余时间-时", remainTimeHour)
  let remainTimeMinute = parseInt(result[29], 16)
  addMessage("剩余时间-分", remainTimeMinute)
  let remainTimeSecond = parseInt(result[30], 16)
  addMessage("剩余时间-秒", remainTimeSecond)
  let realTempUp = parseInt(result[31], 16) * 256 + parseInt(result[32], 16)
  addMessage("实时温度-上管", realTempUp)
  let realTempDown = parseInt(result[33], 16) * 256 + parseInt(result[34], 16)
  addMessage("实时温度-下管", realTempDown)
  let realTempProbe = parseInt(result[35], 16) * 256 + parseInt(result[36], 16)
  addMessage("实时温度-探针", realTempProbe)

  const deviceStatus = parseInt(result[37], 16)
  switch (deviceStatus) {
    case 1:
      addMessage("设备状态", "省电")
      break;
    case 2:
      addMessage("设备状态", "待机")
      break;
    case 3:
      addMessage("设备状态", "工作中")
      break;
    case 4:
      addMessage("设备状态", "烹饪完成")
      break;
    case 5:
      addMessage("设备状态", "预约中")
      break;
    case 6:
      addMessage("设备状态", "永久暂停")
      break;
    case 7:
      addMessage("设备状态", "非永久暂停")
      break;
    case 8:
      addMessage("设备状态", "爱心3秒")
      break;
    case 9:
      addMessage("设备状态", "云菜谱指令设置中")
      break;
    case 10:
      addMessage("设备状态", "自检状态 / 厂检状态")
      break;
    case 11:
      addMessage("设备状态", " 查询版本状态中")
      break;
    case 12:
      addMessage("设备状态", "演示状态/demo模式")
      break;
    case 13:
      addMessage("设备状态", "售后检测模式")
      break;
    case 14:
      addMessage("设备状态", "保留状态（可以继续上一段的烹饪）")
      break;
    case 15:
      addMessage("设备状态", "工作参数设置完成（待启动）")
      break;
    default:
      addMessage("设备状态", "未知状态")
  }
  const stateInfo1 = parseInt(result[38], 16)
  if ((stateInfo1 & 1) > 0)
    addMessage("童锁位", "已上锁")
  else
    addMessage("童锁位", "未锁")

  if ((stateInfo1 & 1 << 1) > 0)
    addMessage("门状态位", "门开")
  else
    addMessage("门状态位", "门关")

  if ((stateInfo1 & 1 << 2) > 0)
    addMessage("水箱位", "缺水箱")
  else
    addMessage("水箱位", "有水箱")

  if ((stateInfo1 & 1 << 3) > 0)
    addMessage("缺水位", "缺水")
  else
    addMessage("缺水位", "不缺水")

  if ((stateInfo1 & 1 << 4) > 0)
    addMessage("换水位", "要换水")
  else
    addMessage("换水位", "不需换水")

  if ((stateInfo1 & 1 << 5) > 0)
    addMessage("是否预热", "预热中")
  else
    addMessage("是否预热", "非预热中")

  if ((stateInfo1 & 1 << 6) > 0)
    addMessage("预热温度位", "预热温度已到")
  else
    addMessage("预热温度位", "预热温度未到")
  if ((stateInfo1 & 1 << 7) > 0)
    addMessage("是否故障标志", "有故障")
  else
    addMessage("是否故障标志", "无故障")
  //


  const orderTimeHour = parseInt(result[42], 16)
  addMessage("预约时间-时", orderTimeHour)
  const orderTimeMinute = parseInt(result[43], 16)
  addMessage("预约时间-分", orderTimeMinute)
  const orderTimeSecond = parseInt(result[44], 16)
  addMessage("预约时间-秒", orderTimeSecond)
  const errorCount = parseInt(result[45], 16)
  addMessage("故障总数", errorCount)
  if (errorCount > 0) {
    for (let i = 0; i < errorCount; i++) {
      const errorClass = parseInt(result[46 + i * 2], 16)
      const errorCode = parseInt(result[47 + i * 2], 16)
      addMessage("故障类别" + i, errorClass)
      addMessage("故障码" + i, errorCode)
    }
  }

  const errorClass = parseInt(result[48 + 2 * errorCount], 16)
  addMessage("故障类别", errorClass)
  const errorCode = parseInt(result[47], 16)
  addMessage("故障码", errorCode)
}



const testNetwork = () => {

  // 网络测试
  const xhr = new XMLHttpRequest();
  xhr.open('GET', '/api', true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        // addLog(xhr.responseText)
        const responseJson = JSON.parse(xhr.responseText)
        addLog(responseJson)
        responseJson.data.datas.forEach(item => {
          addLog(item.link)
        })
        addLog('网络连接成功')
      } else {
        addLog('网络连接失败')
      }
    }
  }
  xhr.send();
}

</script>

<template>
  <!-- <h2>{{ msg }}</h2> -->
  <!-- <div>0x12 0x34 0x56</div> -->
  <div class="card">
    <div class="input-container">
      <textarea v-model="inputText" placeholder="输入指令" class="custom-textarea" rows="5"></textarea>
      <div class="button-group">
        <!-- <button @click="clearText" class="clear-button">清除空格和0x</button> -->
        <button @click="convertToHexArray" class="convert-button">转换为数组</button>
        <button v-show="showTestNetworkButton" @click="testNetwork" class="convert-button">测试网络</button>
      </div>

      <!-- <el-table :data="tableData">
        <el-table-column prop="id" label="id" />
        <el-table-column prop="name" label="姓名" />
        <el-table-column prop="age" label="年龄" />
        <el-table-column prop="email" label="邮箱" />
      </el-table> -->

      <!-- <p v-if="inputText" class="preview-text">预览内容：{{ cleanText }}</p> -->
      <div class="log-container">
        <p>校验码： {{ checkSum }}</p>
        <div class="log-messages">
          <pre v-for="(log, index) in logMessages" :key="index" class="log-message">
            {{ log.key + ": " + log.value }}
          </pre>
        </div>
      </div>

      <table>
        <thead>
          <tr>
            <th v-for="(header, index) in headers" :key="index">{{ header }}</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in tableData" :key="item.id">
            <td>{{ item.id }}</td>
            <td>{{ item.decimalism }}</td>
            <td>{{ '0x' + item.hexadecimal.toString(16).toUpperCase().padStart(2, '0') }}</td>
            <td>{{ item.binary }}</td>
          </tr>
        </tbody>
      </table>



      <div v-if="hexArray.length > 0" class="hex-result">
        <p>十六进制数组：</p>
        <div class="hex-array">
          <span v-for="(hex, index) in hexArray" :key="index" class="hex-item">
            {{ hex }}
          </span>
        </div>
      </div>

    </div>
  </div>
</template>

<style scoped>
.card {
  border: 1px solid #ccc;
  padding: 20px;
  margin: 10px;
  border-radius: 8px;
  background-color: #f9f9f9;
}

table {
  border-collapse: collapse;
  width: 100%;
  margin: 20px 0;
}

th,
td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

th {
  background-color: #f2f2f2;
}

tr:hover {
  background-color: #f5f5f5;
}


.read-the-docs {
  color: #888;
}

.input-container {
  margin: 1rem 0;
  width: 630px;
  max-width: 630px;
}

.custom-textarea {
  width: 610px;
  padding: 0.75rem;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 1rem;
  line-height: 1.5;
  resize: vertical;
  min-height: 100px;
  font-family: inherit;
}

.custom-textarea:focus {
  outline: none;
  border-color: #646cff;
  box-shadow: 0 0 0 2px rgba(100, 108, 255, 0.2);
}

.preview-text {
  margin-top: 0.5rem;
  color: #666;
  white-space: pre-wrap;
}

.button-group {
  margin-top: 0.5rem;
  display: flex;
  gap: 0.5rem;
}

.clear-button,
.convert-button {
  padding: 0.5rem 1rem;
  background-color: #646cff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.9rem;
  transition: background-color 0.2s;
}

.clear-button:hover,
.convert-button:hover {
  background-color: #535bf2;
}

.clear-button:active,
.convert-button:active {
  background-color: #434cff;
}

.hex-result {
  margin-top: 1rem;
  padding: 1rem;
  background-color: #f8f8f8;
  border-radius: 4px;
}

.hex-array {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.hex-item {
  padding: 0.25rem 0.5rem;
  background-color: #e0e0e0;
  border-radius: 3px;
  font-family: monospace;
}

.log-container {
  margin-top: 1rem;
  padding: 1rem;
  background-color: #f0f0f0;
  border-radius: 4px;
  max-height: 400px;
  overflow-y: auto;
}

.log-messages {
  margin-top: 0;
  font-family: monospace;
}

.log-message {
  margin: -1rem 0;
  color: #333;
  white-space: pre-wrap;
  word-break: break-all;
}
</style>
